package com.fiveflavors.suittar.gui;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import say.swing.JFontChooser;

import com.fiveflavors.suittar.growl.GrowlHelper;
import com.fiveflavors.suittar.property.SuittarProperty;
import com.fiveflavors.suittar.resources.SuittarResourceManager;

public class SuittarLoginDialog extends JDialog {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 4986170827674466073L;
	public static final int RESULT_OK = 1;
	public static final int RESULT_CANCEL = 99;

	private String[] intervalValues = new String[] {
			SuittarResourceManager.getMsgString("SuittarLoginDialog.IntervalValues.0"), //$NON-NLS-1$
			SuittarResourceManager.getMsgString("SuittarLoginDialog.IntervalValues.1"),	 //$NON-NLS-1$
			SuittarResourceManager.getMsgString("SuittarLoginDialog.IntervalValues.2"),	 //$NON-NLS-1$
			SuittarResourceManager.getMsgString("SuittarLoginDialog.IntervalValues.3"),	 //$NON-NLS-1$
			SuittarResourceManager.getMsgString("SuittarLoginDialog.IntervalValues.4"),	 //$NON-NLS-1$
			SuittarResourceManager.getMsgString("SuittarLoginDialog.IntervalValues.5")	 //$NON-NLS-1$
		};

	private String[] viewValues = new String[] {
			SuittarResourceManager.getMsgString("SuittarLoginDialog.ViewValues.Public"), //$NON-NLS-1$
			SuittarResourceManager.getMsgString("SuittarLoginDialog.ViewValues.Friends"),	 //$NON-NLS-1$
			SuittarResourceManager.getMsgString("SuittarLoginDialog.ViewValues.Profile"),	 //$NON-NLS-1$
			SuittarResourceManager.getMsgString("SuittarLoginDialog.ViewValues.Replies") //$NON-NLS-1$
		};

	
	private SuittarProperty props = null;
	private JLabel lblId = new JLabel(SuittarResourceManager.getMsgString("SuittarLoginDialog.Username")); //$NON-NLS-1$
	private JTextField frmId = new JTextField();
	
	private JLabel lblPass = new JLabel(SuittarResourceManager.getMsgString("SuittarLoginDialog.Pasword")); //$NON-NLS-1$
	private JPasswordField frmPass = new JPasswordField();
	
	private JToggleButton tglShowProp = new JToggleButton(SuittarResourceManager.getMsgString("SuittarLoginDialog.HideProps")); //$NON-NLS-1$

	private JCheckBox frmChkUseProxy = new JCheckBox(SuittarResourceManager.getMsgString("SuittarLoginDialog.UserProxy")); //$NON-NLS-1$
	
	private JLabel lblProxy = new JLabel(SuittarResourceManager.getMsgString("SuittarLoginDialog.ProxyHost")); //$NON-NLS-1$
	private JTextField frmHost = new JTextField();

	private JLabel lblPort = new JLabel(SuittarResourceManager.getMsgString("SuittarLoginDialog.ProxyPort")); //$NON-NLS-1$
	private JTextField frmPort = new JTextField();
	
	private JButton btnFont = new JButton(SuittarResourceManager.getMsgString("SuittarLoginDialog.Font")); //$NON-NLS-1$
	private JTextField frmFont = new JTextField(""); //$NON-NLS-1$
	
	private JLabel lblInterval = new JLabel(SuittarResourceManager.getMsgString("SuittarLoginDialog.RefreshInterval")); //$NON-NLS-1$
	private JComboBox frmInterval = new JComboBox(intervalValues);
	
	private JLabel lblView = new JLabel(SuittarResourceManager.getMsgString("SuittarLoginDialog.DefaultTImeline")); //$NON-NLS-1$
	private JComboBox frmView = new JComboBox(viewValues);

	private JCheckBox frmChkEnter = new JCheckBox(SuittarResourceManager.getMsgString("SuittarLoginDialog.PressEnterToUpdate")); //$NON-NLS-1$
	private JCheckBox frmChkGrowl = new JCheckBox(SuittarResourceManager.getMsgString("SuittarLoginDialog.NotifyToGrowl")); //$NON-NLS-1$

	private JLabel lblBaseUrl= new JLabel(SuittarResourceManager.getMsgString("SuittarLoginDialog.APIUrl")); //$NON-NLS-1$
	private JTextField frmBaseUrl = new JTextField();
	
	private JCheckBox frmChkSave = new JCheckBox(SuittarResourceManager.getMsgString("SuittarLoginDialog.SaveProperty")); //$NON-NLS-1$
	
	private JButton btnOK = new JButton(SuittarResourceManager.getMsgString("SuittarLoginDialog.Ok")); //$NON-NLS-1$
	private JButton btnCancel = new JButton(SuittarResourceManager.getMsgString("SuittarLoginDialog.CANCEL")); //$NON-NLS-1$
	
	private JPanel proxyPanel = null;
	private JPanel configPanel = null;
	private JPanel savePanel = null;
	
	
	private int result = RESULT_CANCEL;
	
	public SuittarLoginDialog(JFrame parent, SuittarProperty props) {
		
		super(parent,"Suittar!",true); //$NON-NLS-1$
		this.props = props;
		
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
	    setSize(310,500);
	    setLocationRelativeTo(null);
	    setResizable(false);
	    
	    btnFont.addActionListener(new FontActionListener());
	    btnOK.addActionListener(new ButtonActionListener());
	    btnCancel.addActionListener(new ButtonActionListener());
	    frmPass.addActionListener(new ButtonActionListener());
	    btnOK.addKeyListener(new EnterTypedListener());
	    btnCancel.addKeyListener(new EnterTypedListener());
	    frmChkUseProxy.addChangeListener(new CheckBoxChangeListener());
	    tglShowProp.addActionListener(new ToggleActionListener());
	    	    
	    GridBagLayout layout = new GridBagLayout();
	    Container contentPane = getContentPane();
        contentPane.setLayout(layout);
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridheight = 1;
        gbc.gridwidth = 1;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weighty = 0;
        gbc.weightx = 0;
        gbc.fill = GridBagConstraints.VERTICAL;
        gbc.anchor = GridBagConstraints.NORTHWEST;

        //-- Sign in Panel
        gbc.gridy = 0;
	    JPanel signInPanel = createSignInPanel();
        layout.setConstraints(signInPanel, gbc);
        contentPane.add(signInPanel);

        //-- ShowProperties Panel
	    JPanel showPropPanel = new JPanel();
	    showPropPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
	    showPropPanel.add(tglShowProp);
	    showPropPanel.setPreferredSize(new Dimension(300,35));

        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.EAST;
        layout.setConstraints(showPropPanel, gbc);
        contentPane.add(showPropPanel);
        
        //-- Proxy Panel
        gbc.gridy = 2;
	    proxyPanel = createProxyPanel();
        layout.setConstraints(proxyPanel, gbc);
        contentPane.add(proxyPanel);

        //-- Config Panel
        gbc.gridy = 3;
	    configPanel = createConfigPanel();
        layout.setConstraints(configPanel, gbc);
        contentPane.add(configPanel);

        //-- Save Panel
	    savePanel = new JPanel();
	    savePanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
	    savePanel.add(frmChkSave);
	    savePanel.setPreferredSize(new Dimension(300,30));

        gbc.gridy = 4;
        gbc.anchor = GridBagConstraints.EAST;
        layout.setConstraints(savePanel, gbc);
        contentPane.add(savePanel);

        //-- Button Panel
		JPanel btnPanel = new JPanel();
		btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
		btnPanel.add(btnOK);
		btnPanel.add(btnCancel);
		btnPanel.setPreferredSize(new Dimension(300,40));

        gbc.gridy = 5;
        gbc.anchor = GridBagConstraints.SOUTHEAST;
        layout.setConstraints(btnPanel, gbc);
        contentPane.add(btnPanel);

        pack();

	}
	
	private JPanel createSignInPanel() {
		
		Dimension lblPreferredSize = new Dimension(100,20);
		Dimension txtPreferredSize = new Dimension(185,20);
		
		lblPass.setPreferredSize(lblPreferredSize);
		lblId.setPreferredSize(lblPreferredSize);
		frmId.setPreferredSize(txtPreferredSize);
		frmPass.setPreferredSize(txtPreferredSize);
		
		JPanel signInPanel = new JPanel();
	    signInPanel.setPreferredSize(new Dimension(300,70));
	    signInPanel.setBorder(new TitledBorder("Sign in")); //$NON-NLS-1$

	    GridBagLayout layout = new GridBagLayout();
	    signInPanel.setLayout(layout);
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridheight = 1;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.NORTHWEST;
        
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 0.0;
        gbc.weighty = 100.0;
        gbc.gridheight = 1;
        layout.setConstraints(lblId, gbc);
        signInPanel.add(lblId);
        
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.weightx = 100.0;
        gbc.weighty = 100.0;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        layout.setConstraints(frmId, gbc);
        signInPanel.add(frmId);

        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.weightx = 0.0;
        gbc.weighty = 100.0;
        gbc.gridwidth = 1;
        gbc.gridheight = GridBagConstraints.REMAINDER;
        layout.setConstraints(lblPass, gbc);
        signInPanel.add(lblPass);

        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.weightx = 100.0;
        gbc.weighty = 100.0;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        layout.setConstraints(frmPass, gbc);
        signInPanel.add(frmPass);
        
		return signInPanel;
	}
	
	private JPanel createProxyPanel() {

		Dimension lblPreferredSize = new Dimension(100,20);
		Dimension txtPreferredSize = new Dimension(185,20);
		
		lblProxy.setPreferredSize(lblPreferredSize);
		lblPort.setPreferredSize(lblPreferredSize);
		frmHost.setPreferredSize(txtPreferredSize);
		frmPort.setPreferredSize(txtPreferredSize);

	    frmHost.setEnabled(false);
	    frmPort.setEnabled(false);

        JPanel proxyPanel = new JPanel();
	    proxyPanel.setPreferredSize(new Dimension(300,90));
	    proxyPanel.setBorder(new TitledBorder("Proxy")); //$NON-NLS-1$
	    
	    GridBagLayout layout = new GridBagLayout();
	    proxyPanel.setLayout(layout);
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.NORTHWEST;
        
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 0.0;
        gbc.weighty = 100.0;
        gbc.gridwidth = 2;
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        layout.setConstraints(frmChkUseProxy, gbc);
        proxyPanel.add(frmChkUseProxy);
        
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.weightx = 0.0;
        gbc.weighty = 100.0;
        gbc.gridwidth = 1;
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        layout.setConstraints(lblProxy, gbc);
        proxyPanel.add(lblProxy);
        
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.weightx = 100.0;
        gbc.weighty = 100.0;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.gridheight = 1;
        layout.setConstraints(frmHost, gbc);
        proxyPanel.add(frmHost);

        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.weightx = 0.0;
        gbc.weighty = 100.0;
        gbc.gridwidth = 1;
        gbc.gridheight = GridBagConstraints.REMAINDER;
        layout.setConstraints(lblPort, gbc);
        proxyPanel.add(lblPort);

        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.weightx = 100.0;
        gbc.weighty = 100.0;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.gridheight = GridBagConstraints.REMAINDER;
        layout.setConstraints(frmPort, gbc);
        proxyPanel.add(frmPort);

	    return proxyPanel;
	}
	
	private JPanel createConfigPanel() {
		
	    if (System.getProperty("os.name").startsWith("Mac OS")) { //$NON-NLS-1$ //$NON-NLS-2$
    		frmChkGrowl.setEnabled(GrowlHelper.checkGrowlSupport());
	    }
	    else {
	    	frmChkGrowl.setSelected(false);
	    	frmChkGrowl.setEnabled(false);
	    }
	    frmFont.setEditable(false);	    

		Dimension minimumSize = new Dimension(100,20);
		frmFont.setMinimumSize(minimumSize);
		frmBaseUrl.setMinimumSize(minimumSize);

		Dimension minimumSizeCmb = new Dimension(100,25);
		frmInterval.setMinimumSize(minimumSizeCmb);
		frmView.setMinimumSize(minimumSizeCmb);
	    btnFont.setPreferredSize(new Dimension(100,30));

	    JPanel configPanel = new JPanel();
	    configPanel.setPreferredSize(new Dimension(300,200));
	    configPanel.setBorder(new TitledBorder("Config.")); //$NON-NLS-1$

	    GridBagLayout layout = new GridBagLayout();
	    configPanel.setLayout(layout);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridheight = 1;
        gbc.gridwidth = 1;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 100.0;
        gbc.weighty = 100.0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.NORTHWEST;
        
        gbc.fill = GridBagConstraints.HORIZONTAL;
        layout.setConstraints(btnFont, gbc);
        configPanel.add(btnFont);
        
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 1;
        layout.setConstraints(frmFont, gbc);
	    configPanel.add(frmFont);

        gbc.gridy = 1;
        gbc.gridx = 0;
        layout.setConstraints(lblInterval, gbc);
	    configPanel.add(lblInterval);
	    
        gbc.gridx = 1;
        layout.setConstraints(frmInterval, gbc);
	    configPanel.add(frmInterval);
	    
        gbc.gridy = 2;
        gbc.gridx = 0;
        layout.setConstraints(lblView, gbc);
	    configPanel.add(lblView);
	    
        gbc.gridx = 1;
        layout.setConstraints(frmView, gbc);
	    configPanel.add(frmView);

        gbc.gridy = 3;
        gbc.gridx = 0;
        gbc.gridwidth = 2;
        layout.setConstraints(frmChkEnter, gbc);
        configPanel.add(frmChkEnter);

        gbc.gridy = 4;
        layout.setConstraints(frmChkGrowl, gbc);
        configPanel.add(frmChkGrowl);

        gbc.gridy = 5;
        gbc.gridwidth = 1;
        layout.setConstraints(lblBaseUrl, gbc);
        configPanel.add(lblBaseUrl);

        gbc.gridx = 1;
        layout.setConstraints(frmBaseUrl, gbc);
        configPanel.add(frmBaseUrl);
	    
	    return configPanel;
	}
	
	public String getPassword() {
		return String.valueOf(frmPass.getPassword());
	}

	public int getResult() {
		return result;
	}

	public String getUserName() {
		return frmId.getText();
	}
	
	public String getProxyHost() {
		return frmHost.getText();
	}

	public String getProxyPort() {
		return frmPort.getText();
	}

	public boolean isUseProxy() {
		return frmChkUseProxy.isSelected();
	}
	
	public String getBaseUrl() {
		return frmBaseUrl.getText();
	}
	
	public int getRefreshInterval() {
		return frmInterval.getSelectedIndex();
	}
	
	public int getDefaultView() {
		return frmView.getSelectedIndex();
	}
	
	public boolean isEnterToUpdate() {
		return frmChkEnter.isSelected();
	}

	public boolean isSaveProperty() {
		return frmChkSave.isSelected();
	}
	
	public Font getMainPaneFont() {
		return frmFont.getFont();
	}
	
	public boolean isUseGrowl() {
		return frmChkGrowl.isSelected();
	}
	
	public void setProperties() {
		setPropsVisible(false); // default no visible props

		if (!props.isValidData(SuittarProperty.PROPERTY_KEY_ID)) {
			setPropsVisible(true);
		}

		frmId.setText(props.getLooseString(SuittarProperty.PROPERTY_KEY_ID));
		boolean useProxy = props.getLooseBoolean(SuittarProperty.PROPERTY_KEY_USE_PROXY);
		frmChkUseProxy.setSelected(useProxy);
		if (useProxy) {
			frmHost.setText(props.getLooseString(SuittarProperty.PROPERTY_KEY_PROXY_HOST));
			frmPort.setText(props.getLooseString(SuittarProperty.PROPERTY_KEY_PROXY_PORT));
		}

		frmInterval.setSelectedIndex(props.getLooseInt(SuittarProperty.PROPERTY_KEY_REFRESH_INTERVAL));
		frmView.setSelectedIndex(props.getLooseInt(SuittarProperty.PROPERTY_KEY_DEFAULT_VIEW));
		frmChkEnter.setSelected(props.getLooseBoolean(SuittarProperty.PROPERTY_KEY_ENTER_TO_UPDATE));

		frmFont.setFont(new Font(props.getLooseString(SuittarProperty.PROPERTY_KEY_FONT_FAMILY),Font.PLAIN, props.getLooseInt(SuittarProperty.PROPERTY_KEY_FONT_SIZE)));
		frmFont.setText(props.getLooseString(SuittarProperty.PROPERTY_KEY_FONT_FAMILY) + " : " + props.getLooseString(SuittarProperty.PROPERTY_KEY_FONT_SIZE) + "pt"); //$NON-NLS-1$ //$NON-NLS-2$

		if (frmChkGrowl.isEnabled()) {
			frmChkGrowl.setSelected(props.getLooseBoolean(SuittarProperty.PROPERTY_KEY_USE_GROWL));			
		}
		else {
			frmChkGrowl.setSelected(false);			
		}

		frmBaseUrl.setText(props.getLooseString(SuittarProperty.PROPERTY_KEY_BASE_URL));

		if (frmId.getText() != null && frmId.getText().length() > 0) {
			frmPass.requestFocusInWindow();
		}
	}
	
	public void updateProperties() throws IOException {
		props.setProperty(SuittarProperty.PROPERTY_KEY_ID, frmId.getText());
		props.setProperty(SuittarProperty.PROPERTY_KEY_USE_PROXY, String.valueOf(frmChkUseProxy.isSelected()));
		props.setProperty(SuittarProperty.PROPERTY_KEY_PROXY_HOST, frmHost.getText());
		props.setProperty(SuittarProperty.PROPERTY_KEY_PROXY_PORT, frmPort.getText());
		props.setProperty(SuittarProperty.PROPERTY_KEY_REFRESH_INTERVAL, String.valueOf(frmInterval.getSelectedIndex()));
		props.setProperty(SuittarProperty.PROPERTY_KEY_DEFAULT_VIEW, String.valueOf(frmView.getSelectedIndex()));
		props.setProperty(SuittarProperty.PROPERTY_KEY_ENTER_TO_UPDATE, String.valueOf(frmChkEnter.isSelected()));
		props.setProperty(SuittarProperty.PROPERTY_KEY_FONT_FAMILY, frmFont.getFont().getFamily());
		props.setProperty(SuittarProperty.PROPERTY_KEY_FONT_SIZE, String.valueOf(frmFont.getFont().getSize()));
		props.setProperty(SuittarProperty.PROPERTY_KEY_USE_GROWL, String.valueOf(frmChkGrowl.isSelected()));
		props.setProperty(SuittarProperty.PROPERTY_KEY_BASE_URL, frmBaseUrl.getText());
		
		props.saveProperties();
	}

	@Override 
	public void setVisible(boolean b) {
		super.setVisible(b);
		if (b && frmId.getText() != null && frmId.getText().length() > 0) {
			frmPass.requestFocusInWindow();
		}
	}
	
	private void selectFont() {
		JFontChooser fontChooser = new JFontChooser();
		fontChooser.setSelectedFont(frmFont.getFont());
		int result = fontChooser.showDialog(this);
		if (result == JFontChooser.OK_OPTION) {
			Font selFont = fontChooser.getSelectedFont();
			Font tmpFont = new Font(selFont.getName(),Font.PLAIN,selFont.getSize());
			frmFont.setFont(tmpFont);
			frmFont.setText(tmpFont.getFamily() + " : " + tmpFont.getSize() + "pt"); //$NON-NLS-2$
		}
	}
	
	private void setPropsVisible(boolean show) {
		proxyPanel.setVisible(show);
		configPanel.setVisible(show);
		savePanel.setVisible(show);
		tglShowProp.setText(show ? SuittarResourceManager.getMsgString("SuittarLoginDialog.HideProps") : SuittarResourceManager.getMsgString("SuittarLoginDialog.ShowProps")); //$NON-NLS-1$ //$NON-NLS-2$
		pack();
	}

	class ToggleActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			setPropsVisible(tglShowProp.isSelected());
		}
	}
	
	class FontActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			selectFont();
		}
	}
	
	class ButtonActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == btnOK || e.getSource() == frmPass) {
				result = SuittarLoginDialog.RESULT_OK;
			}
			else {
				result = SuittarLoginDialog.RESULT_CANCEL;				
			}
			setVisible(false);
		}
	}
	
	class CheckBoxChangeListener implements ChangeListener {
		public void stateChanged(ChangeEvent e) {
			frmHost.setEnabled(frmChkUseProxy.isSelected());
			frmPort.setEnabled(frmChkUseProxy.isSelected());	
		}		
	}
	
	class EnterTypedListener implements KeyListener {

		public void keyPressed(KeyEvent e) {
			if (e.getKeyCode() == KeyEvent.VK_ENTER) {
				if (e.getSource() == btnOK) {
					btnOK.doClick();
				} else if (e.getSource() == btnCancel) {
					btnCancel.doClick();
				}
			}
		}

		public void keyReleased(KeyEvent e) {
		}

		public void keyTyped(KeyEvent e) {
		}
		
	}

}
